package com.xiangying.config;

import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.github.pagehelper.PageHelper;

@Configuration
@MapperScan("com.xiangying.dao")
public class DruidConfigurer {
	
	private Logger logger = LoggerFactory.getLogger(DruidConfigurer.class);
	
	/** -------------- dataSource pool properties---------------- */
    @Value("${datasource.url}")
    private String url;
    
    @Value("${datasource.username}")
    private String username;
    
    @Value("${datasource.password}")
    private String password;
    
    @Value("${datasource.driverClassName}")
    private String driverClassName;
    
    @Value("${datasource.initialSize}")
    private int initialSize;
    
    @Value("${datasource.minIdle}")
    private int minIdle;
    
    @Value("${datasource.maxActive}")
    private int maxActive;
    
    @Value("${datasource.maxWait}")
    private int maxWait;
    
    @Value("${datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;
    
    @Value("${datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;
    
    @Value("${datasource.validationQuery}")
    private String validationQuery;
    
    @Value("${datasource.testWhileIdle}")
    private boolean testWhileIdle;
    
    @Value("${datasource.testOnBorrow}")
    private boolean testOnBorrow;
    
    @Value("${datasource.testOnReturn}")
    private boolean testOnReturn;
    
    @Value("${datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;
    
    @Value("${datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;
    
    @Value("${datasource.filters}")
    private String filters;
    
    @Value("{datasource.connectionProperties}")
    private String connectionProperties;
    
    /** -------------- pageHelper properties ---------------- */
    @Value("${pagehelper.dialect}")
	private String dialect;
	
	@Value("${pagehelper.reasonable}")
	private String reasonable; 
	
	@Value("${pagehelper.supportMethodsArguments}")
	private String supportMethodsArguments;
	
	@Value("${pagehelper.pageSizeZero}")
	private String pageSizeZero;
	
	@Value("${pagehelper.offsetAsPageNum}")
	private String offsetAsPageNum;
	
	@Value("${pagehelper.params}")
	private String params;
	
	@Value("${mybatis.mapper-locations}")
	private String mapperLocation;
    
    @Bean     
    @Primary  // 在同样的DataSource中，首先使用被标注的DataSource
    public DataSource dataSource(){
    	DruidDataSource datasource = new DruidDataSource();
    	// 驱动配置信息
    	datasource.setUrl(url);
    	datasource.setUsername(username);
    	datasource.setPassword(password);
    	datasource.setDriverClassName(driverClassName);
    	
    	// 连接池配置
    	datasource.setInitialSize(initialSize);
    	datasource.setMinIdle(minIdle);
    	datasource.setMaxActive(maxActive);
    	datasource.setMaxWait(maxWait);
    	datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    	datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    	datasource.setValidationQuery(validationQuery);
    	datasource.setTestWhileIdle(testWhileIdle);
    	datasource.setTestOnBorrow(testOnBorrow);
    	datasource.setTestOnReturn(testOnReturn);
    	datasource.setPoolPreparedStatements(poolPreparedStatements);
    	datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
    	try {
    		if(StringUtils.isNotBlank(filters)){
    			datasource.setFilters(filters);
    		}
		} catch (SQLException e) {
			logger.error("druid configuration initialization filter", e);
		}
    	datasource.setConnectionProperties(connectionProperties);
    	return datasource;
    }
    
    @Bean
    public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
    	logger.info("------------- database start ---------------");
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        DataSource dataSource = dataSource();
        sqlSessionFactoryBean.setDataSource(dataSource);
        
        // 添加分页插件  
        PageHelper pageHelper = new PageHelper();  
        Properties props = new Properties();  
        props.setProperty("dialect", dialect);
        props.setProperty("reasonable", reasonable);  
        props.setProperty("supportMethodsArguments", supportMethodsArguments);  
        props.setProperty("pageSizeZero", pageSizeZero);  
        props.setProperty("params", params); 
        props.setProperty("offsetAsPageNum", offsetAsPageNum);
        
        pageHelper.setProperties(props);  
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});  
        
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocation));
        //sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        logger.info("------------- pageHelper end ---------------");
        return sqlSessionFactoryBean.getObject();
    }
    
    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        registrationBean.addInitParameter("allow", "127.0.0.1");// IP白名单 (没有配置或者为空，则允许所有访问)
        registrationBean.addInitParameter("deny", "192.168.1.61");// IP黑名单 (存在共同时，deny优先于allow)
        registrationBean.addInitParameter("loginUsername", "admin");
        registrationBean.addInitParameter("loginPassword", "admin@xy");
        registrationBean.addInitParameter("resetEnable", "false");
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean druidWebStatViewFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new WebStatFilter());
        registrationBean.addInitParameter("urlPatterns", "/*");
        registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*");
        return registrationBean;
    }
}
